package org.example.reactor;

import org.example.utils.DateUtils;
import org.example.utils.LogUtils;

import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;

public class EchoHandler implements Runnable{

    private SelectionKey sk;

    private String msg;

    private static final int RECEIVING = 0, SENDING = 1;

    private int state = RECEIVING;

    private ByteBuffer buffer;

    public EchoHandler(SelectionKey sk) {
        this.sk = sk;
        this.buffer = ByteBuffer.allocate(1024);
    }

    @Override
    public void run() {
        SocketChannel socketChannel = (SocketChannel) sk.channel();
        buffer.clear();
         try {
             if (state == RECEIVING) {
                 int num = -1;
                 while ((num = socketChannel.read(buffer)) > 0) {
                     buffer.flip();
                     byte[] contents = new byte[num];
                     buffer.get(contents);
                     msg = new String(contents);
                     LogUtils.info(DateUtils.getNow() + "=====>" + msg);
                     buffer.clear();
                 }

                 // 读完之后，写事件就绪
                 sk.interestOps(SelectionKey.OP_WRITE);

                 // 切换模式为发送状态
                 state = SENDING;
             }
             else if (state == SENDING) {
                 buffer.put("welcome to server".getBytes());
                 buffer.flip();
                 socketChannel.write(buffer);
                 buffer.clear();
//                 // 写完之后取消写注册事件
//                 selectionKey.interestOps(selectionKey.interestOps() & (~SelectionKey.OP_WRITE));

                 // 写完之后，读事件就绪
                 sk.interestOps(SelectionKey.OP_READ);

                 // 切换模式为接收状态
                 state = RECEIVING;
             }
         } catch (Exception e) {
            e.printStackTrace();
            sk.cancel();

            try {
                socketChannel.finishConnect();
            }
            catch (Exception e1) {
                e1.printStackTrace();
            }
         }
    }
}
